package com.ybwh.springboot2.common.enums;

import io.github.lukehutch.fastclasspathscanner.FastClasspathScanner;
import io.github.lukehutch.fastclasspathscanner.scanner.ScanResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * <p>
 *
 * </p>
 *
 * @author fanbeibei
 * @version 1.0.0
 * @date 2022/4/2 14:39
 */
@Slf4j
@Component
public class EnumHub implements ApplicationListener {
    // enumId -> CodeTextEnum
    private static ConcurrentHashMap<String, Class<? extends CodeTextEnum>> enumMap = new ConcurrentHashMap<>();

    @Value("${enum.packages}")
    private String enumPackages;


    @Override
    public void onApplicationEvent(ApplicationEvent applicationEvent) {
        if (!(applicationEvent instanceof ContextRefreshedEvent)) {
            return;
        }

        initEnumMap(((ContextRefreshedEvent) applicationEvent).getApplicationContext());
    }

    private synchronized void initEnumMap(ApplicationContext applicationContext) {
        Set<Class<? extends CodeTextEnum>> restClasses = new HashSet<>();
        ScanResult result = new FastClasspathScanner(enumPackages.split(",")).matchClassesImplementing(CodeTextEnum.class, e -> restClasses.add(e)).scan();
        if (CollectionUtils.isEmpty(restClasses)) {
            return;
        }

        for (Class<? extends CodeTextEnum> ec : restClasses) {


            EnumId ei = ec.getAnnotation(EnumId.class);
            if (null == ei) {
                continue;
            }

            if (null != enumMap.get(ei.value())) {
                throw new IllegalStateException("已存在 EnumId:" + ei.value());
            }

            enumMap.put(ei.value(), ec);

        }
    }


    public static List<CodeTextEnumView> getCodeTextEnumViewList(String enumId) {
        Class<? extends CodeTextEnum> clazz = enumMap.get(enumId);
        if (null == clazz) {
            return null;
        }

        return CodeTextEnumUtils.getCodeTextEnumViewList(clazz);
    }


}
